/*****************************************
**  Nom : SALINAS        				**
**	Nom du fichier : ChngAvt.c			**
**	Description : Creation de la liste 	**
**			      chainee				**
**				  						**
**										**
**										**
**	Date : 14/08/2014				    **
**  Statut : Release					**
*****************************************/

/*****************************************
**  Zone de declaration des includes    **
*****************************************/

 #include "struct.h"

/*************************************************
**  Zone de déclaration des variables globales  **
*************************************************/
/***********************************************************************
**  [Fonction LireBases]					      **
**    Lit les fichiers de bases et les transforme en listes chainées  **
**    selon le type indiqué par indic ("r"=regles / "f"=faits)	      **
***********************************************************************/
void CreerListeCh_LireBases(char indic, FILE* fp, ST_FAITS** Tete_Faits, ST_RES** Tete_Res)
{
	int flag=0;
	char mot[MAXSIZE];
	ST_COND *Tete_Cond=NULL;
	memset(mot,0,MAXSIZE*sizeof(char));
	
	if(indic=='f' || indic=='F')
	{
		while((fscanf(fp," %s", mot))!=EOF) //fscanf lit while(mot!=' ')
		{   
			if(mot[(strlen(mot)-1)]==';')
				mot[(strlen(mot)-1)]='\0';
			*Tete_Faits=CreerListeCh_Creer_MaillonFaits(*Tete_Faits,mot);		
		}
	}
	else if(indic=='r' || indic=='R')
	{
		while((fscanf(fp," %s", mot))!=EOF) //fscanf lit while(mot!=' ')
		{   
			if(!strcmp(mot,"->"))
				flag=1;
		
			if(flag==0)
				Tete_Cond=CreerListeCh_Creer_MaillonCond(Tete_Cond,mot);	
			else
			{
				if((fscanf(fp," %s", mot))!=EOF)
				{
					if(mot[(strlen(mot)-1)]==';')
						mot[(strlen(mot)-1)]='\0';
					*Tete_Res=CreerListeCh_Creer_MaillonRes(*Tete_Res,Tete_Cond,mot);
				}
				flag=0;
				Tete_Cond=NULL;
			}		
		}
	}
}

/*******************************************************************
**  [Fonction CreerListeCh_LireRegles]                            **
**    Lit le fichier de règles et le transforme en liste chainée  **
*******************************************************************/
void CreerListeCh_LireRegles(FILE* fp, ST_RES** Tete_Res)
{
	int flag=0;
	char mot[MAXSIZE];
	ST_COND *Tete_Cond=NULL;
	memset(mot,0,MAXSIZE*sizeof(char));
	
	while((fscanf(fp," %s", mot))!=EOF) //fscanf lit while(mot!=' ')
	{   
		//printf("<%s> \n", mot);
		if(!strcmp(mot,"->"))
			flag=1;
		
		if(flag==0)
		{
			//printf("Lance création pour cond <%s>\n",mot);
			Tete_Cond=CreerListeCh_Creer_MaillonCond(Tete_Cond,mot);
		}
		else
		{
			if((fscanf(fp," %s", mot))!=EOF)
			{
				if(mot[(strlen(mot)-1)]==';')
					mot[(strlen(mot)-1)]='\0';
			//	printf("Lance création pour res <%s>\n",mot);
				*Tete_Res=CreerListeCh_Creer_MaillonRes(*Tete_Res,Tete_Cond,mot);
			//	printf("Maillon cree : <%s>\n",Tete_Res->res);
			}
			flag=0;
			Tete_Cond=NULL;
		}		
		
	}
	printf("Maillon cree : <%s>\n",(*Tete_Res)->res);
}

/*******************************************************************
**  [Fonction CreerListeCh_LireFaits]							  **
**    Lit le fichier de faits et le transforme en liste chainée   **
*******************************************************************/
void CreerListeCh_LireFaits(FILE* fp, ST_FAITS** Tete_Faits)
{
	char mot[MAXSIZE];
	memset(mot,0,MAXSIZE*sizeof(char));
	
	while((fscanf(fp," %s", mot))!=EOF) //fscanf lit while(mot!=' ')
	{   
		
		if(mot[(strlen(mot)-1)]==';')
			mot[(strlen(mot)-1)]='\0';
		*Tete_Faits=CreerListeCh_Creer_MaillonFaits(*Tete_Faits,mot);		
	}
	printf("Maillon cree : <%s>\n",(*Tete_Faits)->fait);
}

/******************************************************************
**  [Fonction CreerListeCh_Creer_MaillonCond]			         **
**    Créer le maillon pour une condition dans la liste chainée  **
**    des regles  					         **
******************************************************************/
ST_COND* CreerListeCh_Creer_MaillonCond(ST_COND* pt_tete, char* str)
{  
	ST_COND *new=NULL, *tmp=NULL;
	
	new=(ST_COND*)malloc(sizeof(ST_COND));
	memset(new->cond,0,MAXSIZE*sizeof(char));
	strcpy(new->cond, str);
	new->valid=FALSE;
	new->suiv=NULL;
	
	if(pt_tete==NULL){ 
		//si liste vide ajout en tete
		new->suiv=pt_tete;
		pt_tete=new;
	}
	else{ 
		//sinon ajout en fin
		tmp=pt_tete;
		while(tmp->suiv!=NULL)
			tmp=tmp->suiv;
		
		tmp->suiv=new;
	}
	return pt_tete;
}

/****************************************************************
**  [Fonction CreerListeCh_Creer_MaillonRes]				   **
**    Créer le maillon pour un résultat dans la liste chainée  **
**    des regles  					       					   **
****************************************************************/
ST_RES* CreerListeCh_Creer_MaillonRes(ST_RES* pt_tete, ST_COND* Tete_Cond, char* str)
{  
	ST_RES *new=NULL, *tmp=NULL;
	ST_COND *tmp2=NULL;
	int cptr=0;
	
	new=(ST_RES*)malloc(sizeof(ST_RES));
	memset(new->res,0,MAXSIZE*sizeof(char));
	strcpy(new->res, str);
	new->valid=FALSE;
	new->nb_cond_valid=0;
	new->suiv=NULL;
	new->TeteListCond=Tete_Cond;
	  tmp2=Tete_Cond;
	  while(tmp2!=NULL){
		cptr++;
		tmp2=tmp2->suiv;
	  }
	new->nb_cond=cptr;
	
	if(pt_tete==NULL){
		//si liste vide ajout en tete
		new->suiv=pt_tete;
		pt_tete=new;
	}
	else {
		//sinon ajout en fin
		tmp=pt_tete;
		while(tmp->suiv!=NULL)
			tmp=tmp->suiv;
		
		tmp->suiv=new;
	}
	return pt_tete;
}
/************************************************************
**  [Fonction CreerListeCh_Creer_MaillonFaits]			   **
**    Créer le maillon pour un fait dans la liste chainée  **
**    des faits  					   **
************************************************************/
ST_FAITS* CreerListeCh_Creer_MaillonFaits(ST_FAITS* pt_tete, char* str)
{  
	ST_FAITS *new=NULL, *tmp=NULL;
	int flag=0;
	
	new=(ST_FAITS*)malloc(sizeof(ST_FAITS));
	memset(new->fait,0,MAXSIZE*sizeof(char));
	strcpy(new->fait, str);
	new->suiv=NULL;
	
	if(pt_tete==NULL){
		//si liste vide ajout en tete
		new->suiv=pt_tete;
		pt_tete=new;
	}
	else {
		//sinon ajout en fin
		tmp=pt_tete;
		while(tmp->suiv!=NULL)
		{
			if(!strcmp(tmp->fait,str))
			{
				flag++;
			}
			tmp=tmp->suiv;
		}
		if(flag==0)
			tmp->suiv=new;
	}
	return pt_tete;
}

/*********************************************************
**  [Fonction CreerListeCh_OuvrirFic]				    ** 
**    Ouvre le fichier passé en paramètre dans le mode	**
**    spécifié en paramètre par la variable mode	    **
*********************************************************/
FILE* CreerListeCh_OuvrirFic(char* NomFic,char* mode)
{
	FILE* f=NULL;
	if ((f = fopen(NomFic, mode)) == NULL)
	{
		printf("Erreur d'ouverture du fichier %s !\n",NomFic);
		return NULL;
		//exit(qqch) ??
	}
	else
		return f;
}

/********************************************
**  [Fonction CreerListeCh_FermerFichier]		   **
**    Ferme le fichier passé en paramètre  **
********************************************/
void CreerListeCh_FermerFichier(FILE* fp)
{
	if(fclose(fp))
		printf("Erreur fermeture\n");	
}

/*********************************************************
**  [Fonction CreerListeCh_FreeListeRegles]		   		**
**    Supprime tous les maillons de la liste chainée    **
**    indiquée par indic ("R"=Regles / "F"=Faits)       **
*********************************************************/
void CreerListeCh_FreeListe(char indic, ST_RES** Tete_Res, ST_FAITS** Tete_Faits )
{
	ST_RES* tmpR=*Tete_Res;
	ST_RES* tmpR2=NULL;
	//ST_COND* tmpC=Tete_Res->TeteListCond;
	ST_COND* tmpC=NULL;
	ST_COND* tmpC2=NULL;
	ST_FAITS* tmp=*Tete_Faits;
	ST_FAITS* tmp2=NULL;
	
	if(tmpR != NULL)
	{
		tmpC=(*Tete_Res)->TeteListCond;
		if(indic=='R' || indic=='r')
		{	printf("Debur liberation des resultats \n");
			while(tmpR!=NULL){
				tmpR2=tmpR->suiv;
				printf("Debur liberation des conditions \n");
				while(tmpC!=NULL){
					tmpC2=tmpC->suiv;
					printf("Liberation en cours (C) ...\n");
					free(tmpC);
					printf("Liberation ok (C) \n");
					tmpC=tmpC2;
				}
				printf("Liberation en cours (R) ...\n");
				free(tmpR);
				printf("Liberation ok (R) \n");
				tmpR=tmpR2;
			}
		*Tete_Res = NULL;
		}
	}
	if (tmp != NULL)
	{
		if(indic=='F' || indic=='f')
		{
			printf("Debur liberation des faits \n");
			while(tmp!=NULL){
				tmp2=tmp->suiv;
				printf("Liberation en cours ...\n");
				free(tmp);
				printf("Liberation ok\n");
				tmp=tmp2;
			}
			*Tete_Faits = NULL;
		}
	}
}

/********************************************************
**  [Fonction CreerListeCh_AfficherListe]		   	       **
**    Affiche tous les maillons de la liste chainée    **
**    indiquée par indic ("R"=Regles / "F"=Faits)      **
********************************************************/
void CreerListeCh_AfficherListe(char indic, ST_RES* Tete_Res, ST_FAITS* Tete_Faits)
{
	ST_RES *R=NULL;
	ST_COND *C=NULL;
	ST_FAITS *F=NULL;
	
	if(indic=='R' || indic=='r')
	{
		printf(">AFFICHAGE LISTE REGLES\n");
		R=Tete_Res;
		printf(" -Ex:\n  [RES1: Valide(0\\1)/Nb_cond/Nb_cond_valid.]--{COND1: valid.(0\\1)}-{etc}\n\n");
		while(R!=NULL)
		{
			C=R->TeteListCond;
			printf("  [%s:%d/%d/%d]--",R->res,R->valid,R->nb_cond,R->nb_cond_valid);
			while(C!=NULL)
			{
				printf("{%s:%d}-",C->cond,C->valid);
				C=C->suiv;
			}
			printf("{NULL}\n");
			R=R->suiv;
		}
		printf("  [NULL]\n");
	}
	else if(indic=='F' || indic=='f')
	{
		printf(">AFFICHAGE LISTE FAITS\n");
		F=Tete_Faits;
		printf("   ");
		while(F!=NULL)
		{
			printf("[%s]-",F->fait);
			F=F->suiv;
		}
		printf("[NULL]\n");
	}
	printf("\n");
}

